﻿using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using ZOIL.DataModel;

namespace ZOIL.Library.Behaviors
{
    public class ConnectionBaseViewModel : BaseViewModel, IConnectionShape
    {
        #region private members

        private readonly ObjectManipulationBehavior.DragDropEventHandler _dragChangedHandler;

        private readonly ZLandscapeCanvas.ZLandscapeCanvasEventHandler _elementAddedHandler;

        private readonly ZLandscapeCanvas.ZLandscapeCanvasEventHandler _elementRemovedHandler;

        #endregion

        #region ctor

        public ConnectionBaseViewModel()
        {
            _elementAddedHandler = (sender, e) => OnElementAdded();
            _elementRemovedHandler = (sender, e) => OnElementRemoved();
            _dragChangedHandler = (sender, e) => OnElementDragged();
        }

        #endregion

        public override FrameworkElement View
        {
            get
            {
                return base.View;
            }
            set
            {
                if (base.View != null)
                {
                    View.RemoveHandler(ObjectManipulationBehavior.DragChangedEvent, _dragChangedHandler);
                }

                base.View = value;

                View.AddHandler(ObjectManipulationBehavior.DragChangedEvent, _dragChangedHandler);
                View.AddHandler(ZLandscapeCanvas.ElementAddedEvent, _elementAddedHandler);
                View.AddHandler(ZLandscapeCanvas.ElementRemovedEvent, _elementRemovedHandler);
                
                UpdateConnectionShape();
            }
        }

        protected virtual void OnElementAdded()
        {
            UpdateConnectionShape();
        }

        protected virtual void OnElementRemoved()
        {

        }

        protected virtual void OnElementDragged()
        {
            UpdateConnectionShape();
        }

        #region ConnectionShape

        private Geometry _connectionShape;

        /// <summary>
        /// Gets or sets the ConnectionShape property. This observable property 
        /// indicates
        /// </summary>
        public Geometry ConnectionShape
        {
            get { return _connectionShape; }
            set
            {
                if (_connectionShape != value)
                {
                    var old = _connectionShape;
                    _connectionShape = value;
                    OnConnectionShapeChanged(old, value);
                    RaisePropertyChanged("ConnectionShape");
                }
            }
        }

        /// <summary>
        /// Provides derived classes an opportunity to handle changes to the ConnectionShape property.
        /// </summary>
        protected virtual void OnConnectionShapeChanged(Geometry oldConnectionShape, Geometry newConnectionShape)
        {
        }

        protected virtual void UpdateConnectionShape()
        {
            ConnectionShape = new RectangleGeometry(new Rect(new Point(Canvas.GetLeft(View), Canvas.GetTop(View)), new Size(View.Width, View.Height)));
        }

        #endregion
    }
}
